package com.sea.base.bean

import androidx.annotation.IntRange
import com.sea.base.ext.global.allTrue
import com.sea.base.ext.global.removeIfIterator

/**
 * 基于后端服务器返回，继承即可
 * 可以方便使用下方list.selected...的拓展
 */
interface ISelectedListBean {
    var isSelected: Boolean

    /**
     * 取反
     */
    fun inverterSelected() {
        isSelected = !isSelected
    }
}

/**
 * 原始类的包装器
 */
class SelectedListBeanWrapper<T>(val data: T) : ISelectedListBean {
    override var isSelected = false
}

/**
 * 当前选择的position（单选逻辑）
 */
var <T : ISelectedListBean> List<T>?.selectedPosition: Int
    set(value) {
        this?.forEachIndexed { index, bean ->
            bean.isSelected = index == value
        }
    }
    @IntRange(from = -1L)
    get() = this?.indexOfFirst { it.isSelected } ?: -1

/**
 * 根据bean选中（单选逻辑）
 */
fun <T : ISelectedListBean> List<T>?.setSelected(bean: T) {
    this?.forEach {
        it.isSelected = it == bean
    }
}

/**
 * 全选/全不选（多选逻辑）
 */
var <T : ISelectedListBean> List<T>?.isAllSelected
    get() = this.allTrue { it.isSelected }
    set(value) {
        this?.forEach {
            it.isSelected = value
        }
    }

/**
 * 获取选择的那条数据（单选逻辑）
 */
fun <T : ISelectedListBean> List<T>?.getSelectedData() = this?.getOrNull(selectedPosition)

/**
 * 获取全部选中的数据（多选逻辑）
 */
fun <T : ISelectedListBean> List<T>?.getAllSelectData() = this?.filter { it.isSelected } ?: emptyList()

/**
 * 获取选择的数量（多选逻辑）
 */
val <T : ISelectedListBean> List<T>?.selectCount get() = this?.count { it.isSelected } ?: 0

/**
 * 重置为未选中状态
 */
fun <T : ISelectedListBean> List<T>?.reseatData() {
    this?.forEach {
        it.isSelected = false
    }
}

/**
 * 是否有选中
 * @return true至少有一个选中
 */
fun <T : ISelectedListBean> List<T>?.hasSelected() = selectedPosition >= 0

/**
 * 指定item取反
 */
fun <T : ISelectedListBean> List<T>?.inverterSelected(index: Int) {
    this?.getOrNull(index)?.inverterSelected()
}

/**
 * 删除未选中的数据
 */
fun <T : ISelectedListBean> MutableList<T>?.removeUnselectData() {
    this?.removeIfIterator { item -> !item.isSelected }
}

/**
 * 如果你的数据自是简单的String或不想继承，则使用该拓展来实现选择功能
 */
fun <T> Collection<T>.wrapToSelectedListBean() = this.map { SelectedListBeanWrapper(it) }